cmake_minimum_required(VERSION 3.20)

project(examples)

#自动生成compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include(CMakePrintHelpers)
include(GNUInstallDirs)

find_package(OpenCV REQUIRED)
find_package(OpenGL REQUIRED)
find_package(OpenCL REQUIRED)
find_package(TBB REQUIRED)

cmake_print_variables(OpenCV_INCLUDE_DIRS)
cmake_print_variables(OpenCV_LIBRARIES)
cmake_print_variables(OPENGL_INCLUDE_DIRS)
cmake_print_variables(OPENGL_LIBRARIES)
cmake_print_variables(OpenCL_INCLUDE_DIRS)
cmake_print_variables(OpenCL_LIBRARIES)
cmake_print_variables(TBB_INCLUDE_DIRS)
cmake_print_variables(TBB::tbb)

find_package(OpenMP REQUIRED)
if (OpenMP_CXX_FOUND)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")

    cmake_print_variables(CMAKE_C_FLAGS)
    cmake_print_variables(CMAKE_CXX_FLAGS)
    cmake_print_variables(CMAKE_EXE_LINKER_FLAGS)
endif ()

if (OPENGL_FOUND)
    include_directories(${OpenCV_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS})
else ()
    include_directories(${OpenCV_INCLUDE_DIRS})
endif ()

if (MINGW)
    # set(Qt6_DIR "C:/msys64/mingw64/lib/cmake/Qt6")
    # 定义可能的 MSYS2 根目录（根据实际安装位置调整）
    set(MSYS2_POSSIBLE_ROOTS "C:/msys64" "D:/msys64" "C:/msys2" "D:/msys2")

    # 定义可能的子目录组合
    set(SUBDIR_PATHS
            ucrt64/lib/cmake/Qt6
            mingw64/lib/cmake/Qt6
            clang64/lib/cmake/Qt6
    )

    # 遍历所有可能的路径组合
    foreach(root ${MSYS2_POSSIBLE_ROOTS})
        foreach(sub ${SUBDIR_PATHS})
            set(test_path "${root}/${sub}")
            if(EXISTS "${test_path}/Qt6Config.cmake")
                set(Qt6_DIR "${test_path}")
                break()
            endif()
        endforeach()
        if(Qt6_DIR)
            break()
        endif()
    endforeach()
elseif (MSVC)
    if (DEFINED ENV{Qt6_DIR})
        set(Qt6_DIR "$ENV{Qt6_DIR}")
    endif ()
endif ()
find_package(Qt6 COMPONENTS Core Widgets REQUIRED PATHS ${Qt6_DIR})
if (Qt6_FOUND)
    message(STATUS "Found Qt6: ${Qt6_DIR}")
    message(STATUS "  > Includes: ${Qt6Core_INCLUDE_DIRS}")
    message(STATUS "  > Libraries: ${Qt6Core_LIBRARIES}")
    # Qt 自动化设置
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif ()

# this is heuristically generated, and may not be correct
#find_package(cxxopts CONFIG REQUIRED)
# target_link_libraries(main PRIVATE cxxopts::cxxopts)
#########################
# FOR LEARNING OPENCV 3 #
#########################

###############
### COMPILE ###
###############

# COMPILE EXAMPLES
add_executable(example_02-01 example_02-01.cpp)
add_executable(example_02-02 example_02-02.cpp)
add_executable(example_02-03 example_02-03.cpp)
add_executable(example_02-04 example_02-04.cpp)
add_executable(example_02-05 example_02-05.cpp)
add_executable(example_02-06 example_02-06.cpp)
add_executable(example_02-07 example_02-07.cpp)
add_executable(example_02-08 example_02-08.cpp)
add_executable(example_02-09 example_02-09.cpp)
add_executable(example_02-10 example_02-10.cpp)
add_executable(example_02-11 example_02-11.cpp)
add_executable(example_04-01 example_04-01.cpp)
add_executable(example_04-02 example_04-02.cpp)
add_executable(example_04-03 example_04-03.cpp)
add_executable(example_04-04 example_04-04.cpp)
add_executable(example_05-01 example_05-01.cpp)
add_executable(example_07-01 example_07-01.cpp)
add_executable(example_08-01 example_08-01.cpp)
add_executable(example_08-02 example_08-02.cpp)
add_executable(example_08-03 example_08-03.cpp)
add_executable(example_09-01 example_09-01.cpp)
add_executable(example_09-02 example_09-02.cpp)
add_executable(example_09-03 example_09-03.cpp)
if (OPENGL_FOUND)
    add_executable(example_09-04 example_09-04.cpp)
endif ()
if (Qt6_FOUND)
    add_executable(example_09-05 example_09-05.cpp QMoviePlayer.cpp QMoviePlayer.hpp)
endif ()
# Can only build if you have Qt installed add_executable( example_09-05 example_09-05.cpp )
add_executable(example_10-01 example_10-01.cpp)
add_executable(example_10-02 example_10-02.cpp)
add_executable(example_10-03 example_10-03.cpp)
add_executable(example_11-01 example_11-01.cpp)
add_executable(example_11-02 example_11-02.cpp)
add_executable(example_11-03 example_11-03.cpp)
add_executable(example_12-01 example_12-01.cpp)
add_executable(example_12-02 example_12-02.cpp)
add_executable(example_12-03 example_12-03.cpp)
add_executable(example_12-04 example_12-04.cpp)
add_executable(example_13-01 example_13-01.cpp)
add_executable(example_13-02 example_13-02.cpp)
add_executable(example_13-03 example_13-03.cpp)
add_executable(example_14-01 example_14-01.cpp)
add_executable(example_14-02 example_14-02.cpp)
add_executable(example_14-03 example_14-03.cpp)
add_executable(example_14-04 example_14-04.cpp)
add_executable(example_15-01 example_15-01.cpp)
add_executable(example_15-02 example_15-02.cpp)
add_executable(example_15-03 example_15-03.cpp)
add_executable(example_15-04 example_15-04.cpp)
add_executable(example_15-05 example_15-05.cpp)
add_executable(example_15-BackgroundSubtractor example_15-BackgroundSubtractor.cpp)
add_executable(example_16-01 example_16-01.cpp)
add_executable(example_16-02 example_16-02.cpp)
add_executable(example_17-01 example_17-01.cpp)
add_executable(example_17-02 example_17-02.cpp)
add_executable(example_18-01 example_18-01.cpp)
add_executable(example_18-01_from_disk example_18-01_from_disk.cpp)
add_executable(example_19-01 example_19-01.cpp)
add_executable(example_19-02 example_19-02.cpp)
add_executable(example_19-03 example_19-03.cpp)
add_executable(example_19-04 example_19-04.cpp)
add_executable(example_20-01 example_20-01.cpp)
add_executable(example_20-02 example_20-02.cpp)
add_executable(example_21-01 example_21-01.cpp)
add_executable(example_22-01 example_22-01.cpp)

# NOW COMPILE SOME ANSWERS TO EXERCISES:
add_executable(Exercises_5 Exercises_5.cpp)
add_executable(Exercises_7 Exercises_7.cpp)
add_executable(Exercises_8_1 Exercises_8_1.cpp)
add_executable(Exercises_9_1-2-10-11-12-15-16 Exercises_9_1-2-10-11-12-15-16.cpp)
add_executable(Exercises_9_4 Exercises_9_4.cpp)
add_executable(Exercises_9_5 Exercises_9_5.cpp)
add_executable(Exercises_11-1-2-5-6-7 Exercises_11-1-2-5-6-7.cpp)

################
###   LINK   ###
################
# FIRST LINK EXAMPLES:
target_link_libraries(example_02-01 ${OpenCV_LIBS})
target_link_libraries(example_02-02 ${OpenCV_LIBS})
target_link_libraries(example_02-03 ${OpenCV_LIBS})
target_link_libraries(example_02-04 ${OpenCV_LIBS})
target_link_libraries(example_02-05 ${OpenCV_LIBS})
target_link_libraries(example_02-06 ${OpenCV_LIBS})
target_link_libraries(example_02-07 ${OpenCV_LIBS})
target_link_libraries(example_02-08 ${OpenCV_LIBS})
target_link_libraries(example_02-09 ${OpenCV_LIBS})
target_link_libraries(example_02-10 ${OpenCV_LIBS})
target_link_libraries(example_02-11 ${OpenCV_LIBS})
target_link_libraries(example_04-01 ${OpenCV_LIBS})
target_link_libraries(example_04-02 ${OpenCV_LIBS})
target_link_libraries(example_04-03 ${OpenCV_LIBS})
target_link_libraries(example_04-04 ${OpenCV_LIBS})
target_link_libraries(example_05-01 PRIVATE ${OpenCV_LIBS}) # cxxopts::cxxopts )
target_link_libraries(example_07-01 ${OpenCV_LIBS})
target_link_libraries(example_08-01 ${OpenCV_LIBS})
target_link_libraries(example_08-02 ${OpenCV_LIBS})
target_link_libraries(example_08-03 ${OpenCV_LIBS})
target_link_libraries(example_09-01 ${OpenCV_LIBS})
target_link_libraries(example_09-02 ${OpenCV_LIBS})
target_link_libraries(example_09-03 ${OpenCV_LIBS})
target_link_libraries(example_09-02 ${OpenCV_LIBS})
target_link_libraries(example_09-03 ${OpenCV_LIBS})
if (OPENGL_FOUND)
    target_link_libraries(example_09-04 ${OpenCV_LIBS} ${OPENGL_LIBRARIES})
endif ()
if (Qt6_FOUND)
    target_link_libraries(example_09-05 PRIVATE ${OpenCV_LIBS} Qt6::Core Qt6::Widgets)
endif ()
# Need Qt target_link_libraries( example_09-05 ${OpenCV_LIBS} )
target_link_libraries(example_10-01 ${OpenCV_LIBS})
target_link_libraries(example_10-02 ${OpenCV_LIBS})
target_link_libraries(example_10-03 ${OpenCV_LIBS})
target_link_libraries(example_11-01 ${OpenCV_LIBS})
target_link_libraries(example_11-02 ${OpenCV_LIBS})
target_link_libraries(example_11-03 ${OpenCV_LIBS})
target_link_libraries(example_12-01 ${OpenCV_LIBS})
target_link_libraries(example_12-02 ${OpenCV_LIBS})
target_link_libraries(example_12-03 ${OpenCV_LIBS})
target_link_libraries(example_12-04 ${OpenCV_LIBS})
target_link_libraries(example_13-01 ${OpenCV_LIBS})
target_link_libraries(example_13-02 ${OpenCV_LIBS})
target_link_libraries(example_13-03 ${OpenCV_LIBS})
target_link_libraries(example_14-01 ${OpenCV_LIBS})
target_link_libraries(example_14-02 ${OpenCV_LIBS})
target_link_libraries(example_14-03 ${OpenCV_LIBS})
target_link_libraries(example_14-04 ${OpenCV_LIBS})
target_link_libraries(example_15-01 ${OpenCV_LIBS})
target_link_libraries(example_15-02 ${OpenCV_LIBS})
target_link_libraries(example_15-03 ${OpenCV_LIBS})
target_link_libraries(example_15-04 ${OpenCV_LIBS})
target_link_libraries(example_15-05 ${OpenCV_LIBS})
target_link_libraries(example_15-BackgroundSubtractor ${OpenCV_LIBS})
target_link_libraries(example_16-01 ${OpenCV_LIBS})
target_link_libraries(example_16-02 ${OpenCV_LIBS})
target_link_libraries(example_17-01 ${OpenCV_LIBS})
target_link_libraries(example_17-02 ${OpenCV_LIBS})
target_link_libraries(example_18-01 ${OpenCV_LIBS})
target_link_libraries(example_18-01_from_disk ${OpenCV_LIBS})
target_link_libraries(example_19-01 ${OpenCV_LIBS})
target_link_libraries(example_19-02 ${OpenCV_LIBS})
target_link_libraries(example_19-03 ${OpenCV_LIBS})
target_link_libraries(example_19-04 ${OpenCV_LIBS})
target_link_libraries(example_20-01 ${OpenCV_LIBS})
target_link_libraries(example_20-02 ${OpenCV_LIBS} TBB::tbb)
target_link_libraries(example_21-01 ${OpenCV_LIBS})
target_link_libraries(example_22-01 ${OpenCV_LIBS})

# NOW LINK EXERCISES 
target_link_libraries(Exercises_5 ${OpenCV_LIBS})
target_link_libraries(Exercises_7 ${OpenCV_LIBS})
target_link_libraries(Exercises_8_1 ${OpenCV_LIBS})
target_link_libraries(Exercises_9_1-2-10-11-12-15-16 ${OpenCV_LIBS})
target_link_libraries(Exercises_9_4 ${OpenCV_LIBS})
target_link_libraries(Exercises_9_5 ${OpenCV_LIBS})
target_link_libraries(Exercises_11-1-2-5-6-7 ${OpenCV_LIBS})

# 调用函数处理可执行文件的依赖
add_custom_command(TARGET example_14-01 POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E echo "Copying MSYS2 dependencies..."
        COMMAND ${CMAKE_COMMAND} -D TARGET=$<TARGET_FILE:example_14-01> -P ${CMAKE_CURRENT_SOURCE_DIR}/msys_deps.cmake
)
